#include "Plane.h"
#include <iostream>

using namespace std;


Symbol WPlane::parse(ifstream &file, Symbol curToken) {
    float *numFill;
    vec4 tempN;

    curToken = matchToken(file, curToken, LBrace);

    numFill = parseVector(file, curToken, &curToken, 3);
    normal = vec3(numFill[0], numFill[1], numFill[2]);
    delete numFill;

    curToken = matchToken(file, curToken, Comma);
    if (curToken.isToken) {
        cout << "Expected number: found " 
            << tokenList[curToken.t] << endl;
        exit(1);
    }

    distance = curToken.num;
    curToken = nextToken(file);
    curToken = parseMaterials(file, curToken, this);
    tempN = vec4(normal.x, normal.y, normal.z, 0.0);
    tempN = inverse(transform) * tempN;
    nPrime = normalize(vec3(tempN.x, tempN.y, tempN.z));

    return curToken;
}

bool WPlane::intersect(Ray *r) {
    vec3 d, point;
    vec3 pointOnPlane;
    vec4 pprime, dprime;
    float t;

    pprime = transform * vec4(r->point.x, r->point.y, r->point.z, 1.0);
    dprime = transform * vec4(r->d.x, r->d.y, r->d.z, 0.0);
    point = vec3(pprime.x, pprime.y, pprime.z);
    d = vec3(dprime.x, dprime.y, dprime.z);

    if (normal.z != 0) {
        pointOnPlane = vec3(0.0, 0.0, distance/normal.z);
    }
    else if (normal.y != 0) {
        pointOnPlane = vec3(0.0, distance/normal.y, 0.0);
    }
    else if (normal.x != 0) {
        pointOnPlane = vec3(distance/normal.x, 0.0, 0.0);
    }
    else {
        return false;
    }

    if (dot(normal, d) == 0) {
        return false;
    }

    t = -dot((point - pointOnPlane), normal)/dot(d, normal);

    if (t > 0 && t < r->t) {
        r->t = t;
        return true;
    }

    return false;
}

vec3 WPlane::getNormal(Ray *r) {
    return nPrime;
}

